package com.spring.framework.config;

import com.spring.framework.model.learn.JavaConfig;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.*;

import java.util.function.Predicate;

/**
 * 只有full版配置类才会创建cglib代理
 * 虽然我们在指定配置的时候不标注@Configuration也行，所以加不加注解的区别就在这里
 * 那么加了@Configuration和不加有本质上有什么区别的？
 * 当在配置类中一个@Bean 使用方法的方式引用另一个Bean如果不加注解就会重复加载Bean
 * 如果加了@Configuration  则会在这里创建cglib代理，当调用@Bean方法时会先检测容器中是否存在
 * <p>
 * {@link ConfigurationClassPostProcessor#enhanceConfigurationClasses(ConfigurableListableBeanFactory)}
 *
 * @author xuweizhi
 * @since 2020/12/04 17:12
 */
@Configuration
@ComponentScan(basePackages = {"com.spring.framework.model.learn", "com.spring.framework.ioc.bean"})
public class IocConfig {

	/**
	 * {@link org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass(ConfigurationClass, ConfigurationClassParser.SourceClass, Predicate)}
	 * 解析为 BeanMethod,
	 */
	@Bean
	public String getStringMethod() {
		// Spring 中对于被 @Configuration 注解修饰的类，其 @Bean 方法会被动态代理，从 Spring 方法获取数据
		// 如果没有被 @Configuration 方法修饰，每次调用方法会产生新的对象
		//javaConfig();
		return "bean String";
	}

	@Bean(initMethod = "init", destroyMethod = "destroy")
	public JavaConfig javaConfig() {
		return new JavaConfig();
	}
}
